<?php

require_once("ui.php");
require_once("models/config.php");
require_once("report.general.tab.php");
require_once("report.categories.php");
require_once("report.tab.php");
require_once("report.use.table.php");
require_once("report.tooling.tab.php");
require_once("report.optional.tab.php");
require_once("stats/db.php");

define("INPUT_DEBUGGING_TIME", "editDebuggingTime");
define("INPUT_DEBUGGING_COMPLEXITIES", "selectDebuggingComplexities");
define("INPUT_FEELINGS", "selectDebuggingFeelings");
define("INPUT_DEBUGGING_INTENTS", "selectDebuggingIntents");

define("INPUT_MISSING_DETECTION", "missingDetectionCheckbox");
define("INPUT_MISSING_ROOT_CAUSE", "missingRootCauseCheckbox");
define("INPUT_MISSING_METHOD", "missingMethodCheckbox");
define("INPUT_MISSING_TOOL", "missingToolCheckbox");
define("INPUT_PROBLEM_TEXT_AREA", "textAreaProblems");
define("INPUT_MISSING_INTENT_TEXT_AREA", "textAreaMissingIntent");

define("INPUT_REVISION_ID", "editRevisionIdentifier");
define("INPUT_COMMENT_TEXT_AREA", "textAreaComment");

define("DETECTION_TAB_ID", "detectionTab");
define("ROOT_CAUSE_TAB_ID", "rootCauseTab");
define("METHODS_TAB_ID", "usedMethodsTab");
define("TOOLS_TAB_ID", "toolsTab");

$tabConstants = array();
$tabConstants[DETECTION_TAB_ID]["flagsTable"] = "detection_Flags";
$tabConstants[ROOT_CAUSE_TAB_ID]["flagsTable"] = "root_Cause_Flags";

abstract class ReportTemplate {
	public $tabs = array();
	public $usageTabs = array();

	function constructRadioTab($tabId, $itemTable, $subcategoryTable, $categoryTab) {

		global $db;
		$sql = "SELECT $itemTable.Id AS RootCauseId,
		$itemTable.Name AS RootCauseName,
		$itemTable.SubcategoryId AS SubcategoryId,
		$subcategoryTable.Name AS SubcategoryName,
		$categoryTab.Id AS CategoryId,
		$categoryTab.Name AS CategoryName
		FROM $itemTable JOIN $subcategoryTable ON $itemTable.SubcategoryId = $subcategoryTable.Id JOIN $categoryTab ON $subcategoryTable.CategoryId = $categoryTab.Id
		ORDER BY $categoryTab.Name, $subcategoryTable.Name, $itemTable.Name";

		$db->sql_query($sql);

		$subcatsByCats = array();
		$categoriesInfo = array();
		$subcategoriesInfo = array();
		$sqlItems = $db->sql_fetchall();

		foreach ($sqlItems as $i => $sqlDetectionItem) {
			$categoryId = $sqlDetectionItem['CategoryId'];
				
			if (!isset($subcatsByCats[$categoryId])) {
				$subcatsByCats[$categoryId] = array();
				$categoriesInfo[$categoryId] = $sqlDetectionItem['CategoryName'];
			}

			$subcategories = $subcatsByCats[$categoryId];
				
			$subcategoryId = $sqlDetectionItem['SubcategoryId'];
			if (!isset($subcategories[$subcategoryId])) {
				$subcategories[$subcategoryId] = array();
				$subcategoriesInfo[$subcategoryId] = $sqlDetectionItem['SubcategoryName'];
			}
				
			$item = new SubcategoryItem($sqlDetectionItem['RootCauseId'], $sqlDetectionItem['RootCauseName'], $tabId);
			array_push($subcategories[$subcategoryId], $item);
				
			$subcatsByCats[$categoryId] = $subcategories;
		}

		$categories = array();
		foreach($subcatsByCats as $categoryId => $sqlSubcategories) {
				
			$subcategories = array();
			foreach($sqlSubcategories as $subcategoryId => $subcategoryItems) {

				$subcategoryName = $subcategoriesInfo[$subcategoryId];
				$subcategory = new ReportSubcategory($subcategoryId, $subcategoryName, $subcategoryItems,
						$categoryId,  $tabId);
					
				array_push($subcategories, $subcategory);
			}

			$categoryName = $categoriesInfo[$categoryId];
				
			$category = new ReportCategory($categoryId, $categoryName, $subcategories, $tabId);
			array_push($categories, $category);
		}

		global $tabConstants;

		return new ReportTab($tabId, $tabConstants[$tabId]["flagsTable"], $categories);
	}

	function constructUsageTab($tabId, $itemTable, $categoryTable) {

		global $db;
		$usageOptions = getUsageCategories();

		$sql = "SELECT `$itemTable`.Id AS ToolId,
		`$itemTable`.Name AS ToolName,
		`$categoryTable`.Id AS CategoryId,
		`$categoryTable`.Name AS CategoryName
		FROM `$itemTable` JOIN `$categoryTable` ON `$itemTable`.CategoryId = `$categoryTable`.Id
		ORDER BY `$categoryTable`.Name, `$itemTable`.Name";

		$db->sql_query($sql);
		$sqlItems = $db->sql_fetchall();

		$categoriesInfo = array();
		$toolsByCats = array();

		foreach ($sqlItems as $i => $sqlItem) {
			$categoryId = $sqlItem['CategoryId'];
				
			if (!isset($toolsByCats[$categoryId])) {
				$toolsByCats[$categoryId] = array();
				$categoriesInfo[$categoryId] = $sqlItem['CategoryName'];
			}

			$item = new TableItem($sqlItem['ToolId'], $sqlItem['ToolName'], $usageOptions, $tabId, $categoryId);
			array_push($toolsByCats[$categoryId], $item);
		}

		$categories = array();
		foreach($toolsByCats as $categoryId => $items) {
			$categoryName = $categoriesInfo[$categoryId];
				
			$category = new TableCategory($categoryId, $categoryName, $items, $tabId);
			array_push($categories, $category);
		}

		return new TableTab($tabId, $usageOptions, $categories);
	}

	function insertUsagesToDatabase($reportRecordId, $tab, $tableName, $itemColumn) {
		global $db;
	
		foreach ($tab->categories as $i => $category) {
			foreach ($category->pages as $j => $page) {
				foreach ($page->items as $k => $item) {
	
					$itemGroupName = $item->getRadioGroupName();
					$usageValue = getOriginalPost($itemGroupName);
	
					if (!isset($usageValue)) {
						continue;
					}
	
					if ($usageValue == NOT_USED_ID) {
						continue;
					}
	
					$usageValue = mysql_real_escape_string($usageValue);
	
					$sql = "INSERT INTO $tableName (
					`Id`,
					`Debugging_Report`,
					$itemColumn,
					`Useful_Usage`)
					VALUES (NULL,
					$reportRecordId,
					$item->itemId,
					$usageValue);";
	
					$sqlResult = $db->sql_query($sql);
					if (!$sqlResult) {
						return false;
					}
				}
			}
		}
	
		return true;
	}
	
	abstract public function printTabs();

	private function generateTabsJs() {
		echo 'function createTabs() {
				var subcategory;
				var subcategories;
				var firstSubcategory;
				var category;
				var categories;
				var firstCategory;
				var tab;
					
				var tabs = [];';
			
		foreach ($this->tabs as $h => $tab) {

			reset($tab->categories);
			$firstCategoryKey = key($tab->categories);

			echo 'var categories = [];' . PHP_EOL;
				
			foreach ($tab->categories as $i => $category) {
				echo 'subcategories = [];' . PHP_EOL;

				reset($category->subcategories);
				$firstSubcategoryKey = key($category->subcategories);

				foreach ($category->subcategories as $j => $subcategory) {
					echo 'subcategory = createSubcategory("' . $subcategory->subcategoryId . '", "' .
							$subcategory->getDivId() . '");' . PHP_EOL;

					if ($j == $firstSubcategoryKey) {
						echo 'firstSubcategory = subcategory;' . PHP_EOL;
					}
						
					echo 'subcategories.push(subcategory);' . PHP_EOL;
				}

				echo 'category = createCategory("' . $category->categoryId . '", subcategories, firstSubcategory, "' .
						$category->getSelectId() . '");' . PHP_EOL;
					
				if ($i == $firstCategoryKey) {
					echo 'firstCategory = category;' . PHP_EOL;
				}

				echo 'categories.push(category);' . PHP_EOL;
			}
				
			echo 'tab = createTab("' . $tab->tabId . '", categories, firstCategory, "' . $tab->getSelectId() . '");';
			echo 'tabs.push(tab);';
		}

		echo 'return tabs;';
		echo '}';
	}

	private function generateUsageTabsJs() {
		echo 'function createUsageTabs() {
				var item;
				var items;
				var page;
				var pages;
				var firstPage;
				var category;
				var categories;
				var firstCategory;
				var tab;
					
				var tabs = [];';
			
		foreach ($this->usageTabs as $h => $tab) {

			reset($tab->categories);
			$firstCategoryKey = key($tab->categories);

			echo 'var categories = [];' . PHP_EOL;
				
			foreach ($tab->categories as $i => $category) {
				echo 'pages = [];' . PHP_EOL;

				reset($category->pages);
				$firstPageKey = key($category->pages);

				foreach ($category->pages as $j => $page) {
					echo 'items = [];' . PHP_EOL;
					foreach ($page->items as $k => $item) {
						echo 'item = createUsageItem("' . $item->itemId .'", "' . $item->getRowId() . '");' . PHP_EOL;
						echo 'items.push(item);' . PHP_EOL;
					}
						
					echo 'page = createUsagePage("' . $page->pageId . '", items, "' . $category->categoryId . '");' . PHP_EOL;

					if ($j == $firstPageKey) {
						echo 'firstPage = page;' . PHP_EOL;
					}
						
					echo 'pages.push(page);' . PHP_EOL;
				}

				echo 'category = createUsageCategory("' . $category->categoryId . '", pages, firstPage);' . PHP_EOL;
					
				if ($i == $firstCategoryKey) {
					echo 'firstCategory = category;' . PHP_EOL;
				}

				echo 'categories.push(category);' . PHP_EOL;
			}
				
			echo 'tab = createUsageTab("' . $tab->tabId . '", categories, firstCategory, "' . $tab->getSelectId() . '");';
			echo 'tabs.push(tab);';
		}

		echo 'return tabs;';
		echo '}';
	}

	public function generateJs() {

		echo '<script type="text/javascript">';

		$this->generateTabsJs();
		$this->generateUsageTabsJs();

		$rootObject = 'reportStructure';

		echo 'var ' . $rootObject . ' = new Object();' . PHP_EOL;
		echo $rootObject . '.tabs = createTabs();' . PHP_EOL;
		echo $rootObject . '.usageTabs = createUsageTabs();' . PHP_EOL;

		echo '</script>';
	}
}

class FullReportTemplate extends ReportTemplate {
	function __construct() {

		$this->tabs[DETECTION_TAB_ID] = $this->constructRadioTab(DETECTION_TAB_ID, 'detection_Ways', 'detection_Way_Subcategories', 'detection_Way_Categories');
		$this->tabs[ROOT_CAUSE_TAB_ID] = $this->constructRadioTab(ROOT_CAUSE_TAB_ID, 'root_Causes', 'root_Cause_Subcategories', 'root_Cause_Categories');

		$this->usageTabs[TOOLS_TAB_ID] = $this->constructUsageTab(TOOLS_TAB_ID, 'debugging_Tools', 'debugging_Tool_Categories');
		$this->usageTabs[METHODS_TAB_ID] = $this->constructUsageTab(METHODS_TAB_ID, 'debugging_Methods', 'debugging_Method_Categories');
	}

	function processFormPost($loggedInUser) {

		$errors = array();

		$missingDetection = readPost(INPUT_MISSING_DETECTION);
		$missingRootCause = readPost(INPUT_MISSING_ROOT_CAUSE);
		$missingMethod = readPost(INPUT_MISSING_METHOD);
		$missingTool = readPost(INPUT_MISSING_TOOL);
		$problemTextArea = readPost(INPUT_PROBLEM_TEXT_AREA);

		if($loggedInUser == null) {
			array_push($errors, "User not logged in. (should never happen)");
		}

		$debuggingTime = readPost(INPUT_DEBUGGING_TIME);

		$parsedDebuggingTime = parseDebuggingTime($debuggingTime);
		if ($parsedDebuggingTime['error'] != "") {
			array_push($errors, $parsedDebuggingTime['error']);
			$debuggingTimeString = "";
		} else {
			$debuggingTimeString = $parsedDebuggingTime['time'];
		}

		$problem = ($missingDetection == "on") || ($missingRootCause == "on") ||
		($missingMethod == "on") || ($missingTool == "on") || ($problemTextArea != "");

		$problemText = "";

		if ($missingDetection == "on") {
			$problemText .= "Missing detection" . PHP_EOL;
		}

		if ($missingRootCause == "on") {
			$problemText .= "Missing root cause" . PHP_EOL;
		}

		if ($missingMethod == "on") {
			$problemText .= "Missing method" . PHP_EOL;
		}

		if ($missingTool == "on") {
			$problemText .= "Missing tool" . PHP_EOL;
		}

		if ($problem) {
			if ($problemTextArea == "") {
				array_push($errors, "Please describe what is missing or where is the trouble");
			}
		}

		$problemText .= $problemTextArea;

		$debuggingComplexity = readPost(INPUT_DEBUGGING_COMPLEXITIES);
		if (!isset($debuggingComplexity) || (!($debuggingComplexity > 0)) ) {
			array_push($errors, "Please set the debugging complexity");
		}

		$feelings = readPost(INPUT_FEELINGS);
		if (!isset($feelings) || (!($feelings > 0)) ) {
			array_push($errors, "Please set the feelings");
		}

		$detectionTab = $this->tabs[DETECTION_TAB_ID];
		$detectionRadioValue = readPost($detectionTab->getRadioGroupName());

		if (($detectionRadioValue == null) || ($detectionRadioValue == "")) {
			if ($missingDetection == "on") {
				$detectionRadioValue = "NULL";
			} else {
				array_push($errors, "Please specify the way of detection");
			}
		}

		$rootCauseTab = $this->tabs[ROOT_CAUSE_TAB_ID];
		$rootCauseRadioValue = readPost($rootCauseTab->getRadioGroupName());

		if (($rootCauseRadioValue == null) || ($rootCauseRadioValue == "")) {
			if ($missingRootCause == "on") {
				$rootCauseRadioValue = "NULL";
			} else {
				array_push($errors, "Please specify the root cause");
			}
		}

		if (count($errors) != 0) {
			return $errors;
		}

		$debuggingTimeString = mysql_real_escape_string($debuggingTimeString);
		$problemText = mysql_real_escape_string($problemText);
		$problemText = ($problemText == null) ? "NULL" : "'" . $problemText . "'";

		$debuggingComplexity = mysql_real_escape_string($debuggingComplexity);
		$feelings = mysql_real_escape_string($feelings);
		$detectionRadioValue = mysql_real_escape_string($detectionRadioValue);
		$rootCauseRadioValue = mysql_real_escape_string($rootCauseRadioValue);

		$revisionId = readPost(INPUT_REVISION_ID);
		$revisionId = mysql_real_escape_string($revisionId);
		$revisionId = ($revisionId == null) ? "NULL" : "'" . $revisionId . "'";

		$comment = readPost(INPUT_COMMENT_TEXT_AREA);
		$comment = mysql_real_escape_string($comment);
		$comment = "'" . $comment . "'";

		$sql = "INSERT INTO `debugging_Reports` (`Id`,
		`User`,
		`Debugging_Time`,
		`Report_Time`,
		`Review_Reason`,
		`Root_Cause_Complexity`,
		`Feelings`,
		`Detection_Way`,
		`Root_Cause`,
		`RevisionIdentifier`,
		`Comment`)
		VALUES (NULL,
		$loggedInUser->user_id,
		$debuggingTimeString,
		NOW(),
		$problemText,
		$debuggingComplexity,
		$feelings,
		$detectionRadioValue,
		$rootCauseRadioValue,
		$revisionId,
		$comment
		);";

		global $db;
		$db->sql_query("START TRANSACTION");

		$success = $db->sql_query($sql);
		if(!$success) {
			$sqlError = $db->_sql_error();
				
			array_push($errors, $sqlError['message']);
			$db->sql_query("ROLLBACK");
			return $errors;
		}

		$reportId = $db->get_last_inserted_id();

		$success = $this->insertUsagesToDatabase($reportId, $this->usageTabs[METHODS_TAB_ID],
				'`debugging_Method_Usages`', '`Debugging_Method`');
		if(!$success) {
			$sqlError = $db->_sql_error();
				
			array_push($errors, $sqlError['message']);
			$db->sql_query("ROLLBACK");
			return $errors;
		}

		$success = $this->insertUsagesToDatabase($reportId, $this->usageTabs[TOOLS_TAB_ID],
				'`debugging_Tool_Usages`', '`Debugging_Tool`');
		if(!$success) {
			$sqlError = $db->_sql_error();
				
			array_push($errors, $sqlError['message']);
			$db->sql_query("ROLLBACK");
			return $errors;
		}

		foreach ($this->tabs as $i => $tab) {
			$flags = $tab->getPostedFlags();
				
			$tableName = $tab->flagsTable;
				
			$sql = "INSERT INTO `$tableName` (
			`Id`,
			`Report_Id`";

			foreach ($flags as $j => $flag) {
				$sql .= ", `$flag->column`";
			}

			$sql .= ")
			VALUES (
			NULL ,
			'$reportId'";
				
			foreach ($flags as $j => $flag) {
				$value = $flag->value ? "1" : "0";
				$sql .= ", '$value'";
			}
				
			$sql .= ");";
				
			$success = $db->sql_query($sql);
			if(!$success) {
				$sqlError = $db->_sql_error();

				array_push($errors, $sqlError['message']);
				$db->sql_query("ROLLBACK");
				return $errors;
			}
		}

		$success = $db->sql_query("COMMIT");
		if(!$success) {
			$sqlError = $db->_sql_error();
				
			array_push($errors, $sqlError['message']);
		}

		return $errors;
	}

	public function printTabs() {

		$generalTab = new GeneralTab();
		$generalTab->printTabContent();

		foreach ($this->tabs as $i => $tab) {
			$tab->printTabContent();
		}

		foreach ($this->usageTabs as $i => $tab) {
			$tab->printTabContent();
		}

		$optionalTab = new OptionalTab();
		$optionalTab->printTabContent();
	}
}

class ToolingReportTemplate extends ReportTemplate {

	function __construct() {

		$this->usageTabs[TOOLS_TAB_ID] = $this->constructUsageTab(TOOLS_TAB_ID, 'debugging_Tools', 'debugging_Tool_Categories');
	}

	function processFormPost($loggedInUser) {

		$errors = array();
		
		if($loggedInUser == null) {
			array_push($errors, "User not logged in. (should never happen)");
		}

		$intent = readPost(INPUT_DEBUGGING_INTENTS);
		$missingIntentTextArea = readPost(INPUT_MISSING_INTENT_TEXT_AREA);
		
		$problem = ($missingIntentTextArea != "");
		$problemText = "Missing intent";

		$problemText .= $missingIntentTextArea;

		if (count($errors) != 0) {
			return $errors;
		}

		$intent = mysql_real_escape_string($intent);
		$missingIntentTextArea = mysql_real_escape_string($missingIntentTextArea);
		$missingIntentTextArea = ($missingIntentTextArea == null) ? "NULL" : "'" . $missingIntentTextArea . "'";

		$revisionId = readPost(INPUT_REVISION_ID);
		$revisionId = mysql_real_escape_string($revisionId);
		$revisionId = ($revisionId == null) ? "NULL" : "'" . $revisionId . "'";

		$comment = readPost(INPUT_COMMENT_TEXT_AREA);
		$comment = mysql_real_escape_string($comment);
		$comment = "'" . $comment . "'";

		$sql = "INSERT INTO `intent_Reports` (`Id`,
		`User`,
		`Intent`,
		`Time`,
		`Review_Reason`,
		`Revision_Identifier`,
		`Comment`)
		VALUES (NULL,
		$loggedInUser->user_id,
		$intent,
		NOW(),
		$missingIntentTextArea,
		$revisionId,
		$comment
		);";

		global $db;
		$db->sql_query("START TRANSACTION");

		$success = $db->sql_query($sql);
		if(!$success) {
			$sqlError = $db->_sql_error();

			array_push($errors, $sqlError['message']);
			$db->sql_query("ROLLBACK");
			return $errors;
		}

		$reportId = $db->get_last_inserted_id();

		$success = $this->insertUsagesToDatabase($reportId, $this->usageTabs[TOOLS_TAB_ID],
				'`tools_For_Intents`', '`Tool_Id`');
		if(!$success) {
			$sqlError = $db->_sql_error();

			array_push($errors, $sqlError['message']);
			$db->sql_query("ROLLBACK");
			return $errors;
		}

		$success = $db->sql_query("COMMIT");
		if(!$success) {
			$sqlError = $db->_sql_error();

			array_push($errors, $sqlError['message']);
		}

		return $errors;
	}

	public function printTabs() {

		$generalTab = new ToolingTab();
		$generalTab->printTabContent();

		foreach ($this->tabs as $i => $tab) {
			$tab->printTabContent();
		}

 		foreach ($this->usageTabs as $i => $tab) {
 			$tab->printTabContent();
 		}

 		$optionalTab = new OptionalTab();
 		$optionalTab->printTabContent();
	}
}
	?>